<?php

/**
 * 作者：云喵软件开发工作室
 * 官网：https://www.meoyun.com
 */

namespace app\api\controller;

use app\model\MessageModel;
use Respect\Validation\Exceptions\ValidationException;
use Respect\Validation\Validator as v;
use support\Request;
use support\Response;

/**
 * 消息控制器
 */
class Message extends BaseApi
{
    /**
     * 验证消息类型参数
     *
     * @param array $data
     * @return array
     * @throws ValidationException
     */
    private function validateTypeParam(array $data): array
    {
        $validTypes = [
            MessageModel::TYPE_LIKE,
            MessageModel::TYPE_FAVORITE,
            MessageModel::TYPE_COMMENT,
            MessageModel::TYPE_FOLLOW,
            MessageModel::TYPE_SYSTEM
        ];

        return v::input($data, [
            'type' => v::optional(
                v::oneOf(
                    // 单个整数类型
                    v::intType()->in($validTypes),
                    // 整数数组类型
                    v::arrayType()->each(v::intType()->in($validTypes))
                )
            )->setName('消息类型')
        ]);
    }

    /**
     * 构建未读消息查询
     *
     * @param string $userId
     * @param int|null $type
     * @return \Illuminate\Database\Eloquent\Builder
     */
    private function buildUnreadQuery(string $userId, ?int $type = null)
    {
        $query = MessageModel::where('to_user_id', $userId)->where('is_read', 0);

        if ($type !== null) {
            $query->where('type', $type);
        }

        return $query;
    }
    /**
     * 获取未读消息数量统计
     * @param Request $request
     * @return Response
     */
    public function getUnreadCount(Request $request): Response
    {
        $userId = $this->getUserId(false);

        try {
            $params = $this->validateTypeParam($request->all());
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        // 如果指定了消息类型，则按类型筛选
        if (isset($params['type'])) {
            return $this->success(['count' => $this->buildUnreadQuery($userId, $params['type'])->count()]);
        }

        // 直接统计总未读数量
        $total = $this->buildUnreadQuery($userId)->count();

        // 按类型分组统计
        $counts = $this->buildUnreadQuery($userId)
            ->selectRaw('type, COUNT(*) as count')
            ->groupBy('type')
            ->get()
            ->pluck('count', 'type')
            ->toArray();

        //最新一条的系统消息
        $newSystem = MessageModel::where([
            ["to_user_id","=", $userId],
            ["type","=", MessageModel::TYPE_SYSTEM]
        ])->orderBy('created_at','desc')->first();

        return $this->success([
            'total' => $total,
            'like_count' => $counts[MessageModel::TYPE_LIKE] ?? 0,
            'favorite_count' => $counts[MessageModel::TYPE_FAVORITE] ?? 0,
            'comment_count' => $counts[MessageModel::TYPE_COMMENT] ?? 0,
            'follow_count' => $counts[MessageModel::TYPE_FOLLOW] ?? 0,
            'system_count' => $counts[MessageModel::TYPE_SYSTEM] ?? 0,
            'new_system' => $newSystem
        ]);
    }

    /**
     * 获取消息列表
     *
     * @param Request $request
     * @return Response
     */
    public function getUserMsgList(Request $request): Response
    {
        $userId = $this->getUserId();

        try {
            $params = $this->validateTypeParam($request->all());
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        $query = MessageModel::where('to_user_id', $userId)
            ->with(['user', 'toUser','post'])
            ->orderBy('created_at', 'desc');

        // 按类型筛选
        if (isset($params['type'])) {
            if (is_array($params['type'])) {
                // 数组类型，使用 whereIn 查询
                $query->whereIn('type', $params['type']);
            } else {
                // 单个类型，使用 where 查询
                $query->where('type', $params['type']);
            }
        }

        return $this->dataByPage($query->paginate());
    }

    /**
     * 标记单条消息为已读
     *
     * @param Request $request
     * @return Response
     */
    public function markAsRead(Request $request): Response
    {
        $userId = $this->getUserId();

        try {
            $params = v::input($request->all(), [
                'message_id' => v::stringType()->notEmpty()->setName('消息ID')
            ]);
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        $message = MessageModel::where('id', $params['message_id'])
            ->where('to_user_id', $userId)
            ->first();

        if (!$message) {
            return $this->fail('消息不存在或无权限访问');
        }

        if ($message->is_read) {
            return $this->success(null, '消息已经是已读状态');
        }

        $message->update(['is_read' => 1]);

        return $this->success(null, '消息已标记为已读');
    }

    /**
     * 标记所有消息为已读
     *
     * @param Request $request
     * @return Response
     */
    public function markAllAsRead(Request $request): Response
    {
        $userId = $this->getUserId();

        try {
            $params = $this->validateTypeParam($request->all());
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        $query = $this->buildUnreadQuery($userId, $params['type'] ?? null);
        $affectedRows = $query->update(['is_read' => 1]);

        return $this->success(['affected_rows' => $affectedRows], '消息已全部标记为已读');
    }
}
